package com.java110.mall.cart.cmd.inoutOrder;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.java110.core.annotation.Java110Cmd;
import com.java110.core.context.CmdContextUtils;
import com.java110.core.context.ICmdDataFlowContext;
import com.java110.core.event.cmd.Cmd;
import com.java110.core.event.cmd.CmdEvent;
import com.java110.core.factory.GenerateCodeFactory;
import com.java110.dto.app.AppDto;
import com.java110.dto.inoutOrder.InoutOrderDto;
import com.java110.dto.product.ProductSpecValueDto;
import com.java110.dto.user.UserDto;
import com.java110.intf.cart.IInoutOrderInnerServiceSMO;
import com.java110.intf.cart.IInoutOrderProductInnerServiceSMO;
import com.java110.intf.goods.IProductSpecValueInnerServiceSMO;
import com.java110.intf.user.IUserV1InnerServiceSMO;
import com.java110.po.inoutOrder.InoutOrderPo;
import com.java110.po.inoutOrder.InoutOrderProductPo;
import com.java110.po.product.ProductSpecValuePo;
import com.java110.utils.exception.CmdException;
import com.java110.utils.util.Assert;
import com.java110.utils.util.StringUtil;
import com.java110.vo.ResultVo;
import org.springframework.beans.factory.annotation.Autowired;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

@Java110Cmd(serviceCode = "/inoutOrder/saveInoutOrder")
public class SaveInoutOrderCmd extends Cmd {

    @Autowired
    private IUserV1InnerServiceSMO userInnerServiceSMOImpl;


    @Autowired
    private IProductSpecValueInnerServiceSMO productSpecValueInnerServiceSMOImpl;

    @Autowired
    private IInoutOrderInnerServiceSMO inoutOrderInnerServiceSMOImpl;

    @Autowired
    private IInoutOrderProductInnerServiceSMO iInoutOrderProductInnerServiceSMOImpl;

    @Override
    public void validate(CmdEvent event, ICmdDataFlowContext cmdDataFlowContext, JSONObject reqJson) throws CmdException {
        Assert.hasKeyAndValue(reqJson, "orderType", "请求报文中未包含orderType");
        Assert.hasKeyAndValue(reqJson, "shopId", "请求报文中未包含商铺");
    }

    @Override
    public void doCmd(CmdEvent event, ICmdDataFlowContext cmdDataFlowContext, JSONObject reqJson) throws CmdException {
        String appId = cmdDataFlowContext.getReqHeaders().get("app-id");
        String userId = CmdContextUtils.getUserId(cmdDataFlowContext);
        reqJson.put("appId",appId);

        UserDto userDto = new UserDto();
        userDto.setUserId(userId);
        List<UserDto> userDtos = userInnerServiceSMOImpl.queryUsers(userDto);

        Assert.listOnlyOne(userDtos, "未包含用户信息");

        if (!reqJson.containsKey("inoutOrderProducts")) {
            throw new IllegalArgumentException("请求报文格式错误");
        }

        JSONArray inoutOrderProducts = reqJson.getJSONArray("inoutOrderProducts");
        if (inoutOrderProducts == null || inoutOrderProducts.size() < 1) {
            throw new IllegalArgumentException("未包含商品");
        }

        InoutOrderPo inoutOrderPo = new InoutOrderPo();
        inoutOrderPo.setOrderId(GenerateCodeFactory.getGeneratorId(GenerateCodeFactory.CODE_PREFIX_orderId));
        inoutOrderPo.setShopId(reqJson.getString("shopId"));
        inoutOrderPo.setState(InoutOrderDto.STATE_W);
        inoutOrderPo.setOrderType(reqJson.getString("orderType"));
        inoutOrderPo.setPersonId(userId);

        inoutOrderPo.setPersonName(userDtos.get(0).getName());
        if (!StringUtil.isNullOrNone(reqJson.getString("relOrderId"))) {
            inoutOrderPo.setRelOrderId(reqJson.getString("relOrderId"));
        }
        inoutOrderPo.setRemark(reqJson.getString("remark"));
        //开始保存 inoutOrderProduct
        InoutOrderProductPo inoutOrderProductPo = null;
        List<InoutOrderProductPo> inoutOrderProductPos = new ArrayList<>();
        for (int inoutOrderProductIndex = 0; inoutOrderProductIndex < inoutOrderProducts.size(); inoutOrderProductIndex++) {
            inoutOrderProductPo = new InoutOrderProductPo();
            inoutOrderProductPo.setRsId(reqJson.getString("rsId"));
            inoutOrderProductPo.setSupplierName(reqJson.getString("supplierName"));
            //inoutOrderProductPo.setPrice(inoutOrderProducts.getJSONObject(inoutOrderProductIndex).getString("price"));
            inoutOrderProductPo.setPrice(inoutOrderProducts.getJSONObject(inoutOrderProductIndex).getString("costPrice"));
            inoutOrderProductPo.setProdCount(inoutOrderProducts.getJSONObject(inoutOrderProductIndex).getString("count"));
            BigDecimal price = new BigDecimal(Double.parseDouble(inoutOrderProductPo.getPrice()));
            price = price.multiply(new BigDecimal(Double.parseDouble(inoutOrderProductPo.getProdCount()))).setScale(2, BigDecimal.ROUND_HALF_EVEN);
            inoutOrderProductPo.setAmount(price.doubleValue() + "");
            inoutOrderProductPo.setItemId(GenerateCodeFactory.getGeneratorId("11"));
            inoutOrderProductPo.setOrderId(inoutOrderPo.getOrderId());
            inoutOrderProductPo.setProductId(inoutOrderProducts.getJSONObject(inoutOrderProductIndex).getString("productId"));
            inoutOrderProductPo.setProdName(inoutOrderProducts.getJSONObject(inoutOrderProductIndex).getString("prodName"));
            inoutOrderProductPo.setShopId(inoutOrderPo.getShopId());
            inoutOrderProductPo.setState(InoutOrderDto.STATE_W);
            inoutOrderProductPo.setValueId(inoutOrderProducts.getJSONObject(inoutOrderProductIndex).getString("valueId"));
            inoutOrderProductPo.setRemark(inoutOrderProducts.getJSONObject(inoutOrderProductIndex).getString("remark"));
            inoutOrderProductPo.setSpecName(inoutOrderProducts.getJSONObject(inoutOrderProductIndex).getString("specName"));

            inoutOrderProductPos.add(inoutOrderProductPo);

            //如果是出库 判断库存是否足够
            if (InoutOrderDto.ORDER_TYPE_IN.equals(inoutOrderPo.getOrderType())) {
                updateProduceSpecStock(reqJson, inoutOrderProducts.getJSONObject(inoutOrderProductIndex), inoutOrderProductPo,inoutOrderPo);
                continue;
            }

            ProductSpecValueDto productSpecValueDto = new ProductSpecValueDto();
            productSpecValueDto.setShopId(inoutOrderProductPo.getShopId());
            productSpecValueDto.setValueId(inoutOrderProductPo.getValueId());
            productSpecValueDto.setProductId(inoutOrderProductPo.getProductId());
            List<ProductSpecValueDto> productSpecValueDtos = productSpecValueInnerServiceSMOImpl.queryProductSpecValues(productSpecValueDto);

            Assert.listOnlyOne(productSpecValueDtos, "商品不存在");

            long stock = Long.parseLong(productSpecValueDtos.get(0).getStock());

            if (stock < Long.parseLong(inoutOrderProductPo.getProdCount())) {
                throw new IllegalArgumentException(inoutOrderProductPo.getProdName() + "库存不足");
            }
            //更新库存
            updateProduceSpecStock(reqJson, inoutOrderProducts.getJSONObject(inoutOrderProductIndex), inoutOrderProductPo,inoutOrderPo);

        }


        int flag = iInoutOrderProductInnerServiceSMOImpl.saveInoutOrderProducts(inoutOrderProductPos);

        if (flag < 1) {
            throw new IllegalArgumentException("提交失败");
        }

        flag = inoutOrderInnerServiceSMOImpl.saveInoutOrder(inoutOrderPo);

        if (flag < 1) {
            throw new IllegalArgumentException("提交失败");
        }
        cmdDataFlowContext.setResponseEntity(ResultVo.createResponseEntity(ResultVo.CODE_OK, "保存成功"));
    }

    /**
     * 更新库存
     *
     * @param reqJson
     * @param prodSpec
     * @param inoutOrderProductPo
     */
    private void updateProduceSpecStock(JSONObject reqJson, JSONObject prodSpec, InoutOrderProductPo inoutOrderProductPo,InoutOrderPo inoutOrderPo) {
        inoutOrderProductPo.setActCount(inoutOrderProductPo.getProdCount());

        ProductSpecValuePo productSpecValuePo = new ProductSpecValuePo();
        productSpecValuePo.setProductId(prodSpec.getString("productId"));
        productSpecValuePo.setValueId(prodSpec.getString("valueId"));
        if(InoutOrderDto.ORDER_TYPE_IN.equals(reqJson.getString("orderType"))) {
            productSpecValuePo.setAddStock(inoutOrderProductPo.getActCount());
        }else{
            productSpecValuePo.setMinusStock(inoutOrderProductPo.getActCount());
        }
        if (AppDto.MALL_STAFF_APP_ID.equals(reqJson.getString("appId"))) {
            inoutOrderProductPo.setState(InoutOrderDto.STATE_C);
            inoutOrderPo.setState(InoutOrderDto.STATE_C);
        }
        //更新库存中数量
        int flag = productSpecValueInnerServiceSMOImpl.updateProductSpecValue(productSpecValuePo);
        if (flag < 0) {
            throw new CmdException("更新库存失败");
        }
    }
}
